﻿using System;
using System.Linq.Expressions;

namespace FluentlyXml.Core.DSL
{
	/// <summary> </summary>
	internal class PropertySerializationSpec<T> : TypeSerializationSpec<T>, IPropertyOrTypeSerializationSpec<T>, IInitialPropertySerializationSpec<T>
	{
		private readonly Expression<Func<T, object>> _expression;
		private readonly ISerializationConfig _config;

		public PropertySerializationSpec(Expression<Func<T, object>> expression, ISerializationConfig config) 
			: base(config)
		{
			_expression = expression;
			_config = config;
		}

		/// <summary> </summary>
		public IPropertyOrTypeSerializationSpec<T> AsAttribute()
		{
			return this;
		}

		/// <summary> </summary>
		public IPropertyOrTypeSerializationSpec<T> AsElement()
		{
			return AsElement(_expression.GetProperty().Name);
		}

		public IPropertyOrTypeSerializationSpec<T> AsElement(string elementName)
		{
			_config.SerializePropertyAsElement(typeof(T), _expression.GetProperty(), elementName);
			return this;
		}

		/// <summary> </summary>
		public IPropertyOrTypeSerializationSpec<T> AsArray()
		{
			_config.SerializePropertyAsArray(typeof(T), _expression.GetProperty());
			return this;
		}

		public IPropertyOrTypeSerializationSpec<T> Named(string name)
		{
			return this;
		}

		public IPropertyOrTypeSerializationSpec<T> SerializeIf(Func<T, bool> selector)
		{
			return this;
		}

		/// <summary> </summary>
		ITypeSerializationSpec<T> IInitialPropertySerializationSpec<T>.Using(Func<T, object> selector)
		{
			_config.SerializePropertyAsElementUsing(typeof(T), _expression.GetProperty(), _expression.GetProperty().Name, (object o) => selector((T)o));
			return this;
		}

	}
}